﻿using DeHeng_Mes.Constant;
using DeHeng_Mes.Dao;
using DeHeng_Mes.Model.OrderSingleton;
using DeHeng_Mes.Model.Table;
using DeHeng_Mes.Utils;
using S7.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace DeHeng_Mes.PlcService
{
    public class VerificationService
    {
        #region 成员实例
        OrderDao orderDao = new OrderDao();
        #endregion

        public (int, List<int>) CodeVerification(string station, string code, List<string> stationList)
        {
            // 初始化报警码
            List<int> errorCodes = new List<int>();

            // 初始化NG校验(有出站记录)
            bool ngStationIsGoOut = false;

            try
            {
                // 格式校验
                bool isOk = CodeIsOk(code);

                // 重码校验
                bool isSave = CodeIsSave(code, station);

                // 产量校验
                bool productionIsOk = OrderProductionIsOk(station);

                // 跳工序校验
                (bool operationIsOk, int errorcode) = OperationIsOk(code, station, stationList);

                switch (station)
                {
                    case SystemConstant.NgStation:
                        bool ngIsSave = orderDao.NgStationIsSave(code, station, "1");

                        ngStationIsGoOut = !ngIsSave;
                        break;
                }

                isOk = false;

                if (isOk || isSave || productionIsOk || ngStationIsGoOut || operationIsOk)
                {
                    if (isOk)
                    {
                        // 格式校验报警
                        errorCodes.Add(1200);
                    }

                    if (isSave)
                    {
                        // 重码报警
                        errorCodes.Add(1500);
                    }

                    if (productionIsOk)
                    {
                        // 产量报警
                        errorCodes.Add(1501);
                    }

                    if (ngStationIsGoOut)
                    {
                        // 不是NG出站的件，从NG上线报警
                        errorCodes.Add(1502);
                    }

                    if (operationIsOk)
                    {
                        errorCodes.Add(errorcode);
                    }

                    return (2, errorCodes);
                }

                return (1, errorCodes);
            }
            catch (Exception ex)
            {
                Tools.ProduceLogTextError($"[{station}]触发校验失败，原因是[{ex.Message}]");

                return (-1, errorCodes);
            }
        }

        /// <summary>
        /// 检测是否存在跳工序
        /// </summary>
        /// <param name="code"></param>
        /// <param name="station"></param>
        /// <returns></returns>
        private (bool, int) OperationIsOk(string code, string station, List<string> stationList)
        {
            string lastStation = MappingTable.GetLastStation(station);

            if (!string.IsNullOrEmpty(lastStation))
            {
                List<PartProcess> partProcesses = orderDao.GetStationData(code, lastStation);

                if (partProcesses.Count == 0)
                {
                    // 无数据
                    return (true, 1503);
                }
                else
                {
                    PartProcess partProcess = partProcesses.OrderByDescending(x => x.Id).FirstOrDefault();

                    if (Tools.IsDateTimeValid(partProcess.StartTime) && !Tools.IsDateTimeValid(partProcess.EndTime))
                    {
                       /* // 无进有出，默认补齐
                        partProcess.StartTime = partProcess.EndTime.AddMinutes(-1);

                        orderDao.UpDateStationStartTime(partProcess);*/

                        Tools.ProduceLogTextError($"[{station}]出现一条无进有出数据，追溯码[{code}]");

                        return (false, 0);
                    }
                    else if (!Tools.IsDateTimeValid(partProcess.StartTime) && Tools.IsDateTimeValid(partProcess.EndTime))
                    {
                        Tools.ProduceLogTextError($"[{station}]出现一条有进无出数据，追溯码[{code}]");
                        // 有进无出
                        return (true, 1504);
                    }
                }
            }

            return (false, 0);
        }

        /// <summary>
        /// 检测重码
        /// </summary>
        /// <param name="code"></param>
        /// <param name="station"></param>
        /// <returns></returns>
        private bool CodeIsSave(string code, string station)
        {
            List<PartProcess> partProcesses = orderDao.CodeIsSave(code, station);

            List<PartProcess> partProcesses1 = partProcesses.Where(x => x.EndTime.Year == 1900).ToList();

            if (partProcesses.Count != partProcesses1.Count)
            {
                return true;
            }

            return false;
/*
            switch (station)
            {
                case SystemConstant.OP25:

                    if (isSave)
                    {
                        // 存在重码，检测是否有NG入站记录
                        bool ngIsSave = orderDao.NgStationIsSave(code, station, "2");

                        return !ngIsSave;
                    }

                    return isSave;
                default:
                    return isSave;
            }*/
        }

        /// <summary>
        /// 产量校验
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        private bool OrderProductionIsOk(string station)
        {
            OrderSingletonModel orderSingletonModel = OrderSingleton.GetOrderId(station);

            if (orderSingletonModel == null)
                return false;

            if (orderSingletonModel.ProducessNumNow >= orderSingletonModel.ProducessNum)
                return true;

            return false;
        }

        #region 私有方法
        /// <summary>
        /// 格式校验
        /// </summary>
        /// <param name="code"></param>
        private bool CodeIsOk(string code)
        {
            // 正则表达式1：匹配第一种格式 "LAC-51010298 5FK 2A230631 X200001 230831 00001"
            Regex regex1 = new Regex(@"^LAC-\d{8} [A-Z0-9]{3} \d{1}[A-Z]{1}\d{6} [A-Z0-9]{1}\d{6} \d{6} \d{5}$");

            // 正则表达式2：匹配第二种格式 "LAC-56010050 01 5FK 2A230631 X200001 230831 A 00001"
            Regex regex2 = new Regex(@"^LAC-\d{8} \d{2} [A-Z0-9]{3} 2A\d{6} [A-Z0-9]{1}\d{6} \d{6} [A-Z] \d{5}$");

            // 正则表达式3：匹配第三种格式 "LAC-84001059 08 240705 A 00001"
            Regex regex3 = new Regex(@"^LAC-\d{8} \d{2} \d{6} [A-Z] \d{5}$");

            // 正则表达式4：匹配第四种格式 "LAC-56010050-1 01 5FK 2A230631 X200001 230831 A 00001"
            Regex regex4 = new Regex(@"^LAC-\d{8}-\d{1} \d{2} [A-Z0-9]{3} 2A\d{6} [A-Z0-9]{1}\d{6} \d{6} [A-Z] \d{5}$");

            bool a = regex1.IsMatch(code);
            bool b = regex2.IsMatch(code);
            bool c = regex3.IsMatch(code);
            bool d = regex4.IsMatch(code);

            if (!(a || b || c || d))
                return true;
            return false;
        }
        #endregion
    }
}
